/**
 * 测站类型管理 Service
 * 
 * 提供测站类型的增删改查等业务逻辑
 * 
 * @author: [开发者名称]
 * @date: [创建日期]
 */

import { Provide } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { StationType1 } from '../entity/stationType.entity';
import {
  CreateStationTypeDTO,
  UpdateStationTypeDTO,
  QueryStationTypeDTO,
  StationTypeResponseDTO,
  PageResultDTO,
  BatchImportStationTypeDTO,
  BatchDeleteDTO
} from '../dto/stationType.dto';

@Provide()
export class StationTypeService {
  @InjectEntityModel(StationType1)
  stationTypeRepository: Repository<StationType1>;

  /**
   * 创建测站类型
   */
  async create(createStationTypeDTO: CreateStationTypeDTO): Promise<StationTypeResponseDTO> {
    // 检查编码是否已存在
    const existingType = await this.stationTypeRepository.findOne({
      where: { stationTypeCode: createStationTypeDTO.stationTypeCode }
    });
    
    if (existingType) {
      throw new Error('测站类型编码已存在');
    }

    const stationType = this.stationTypeRepository.create({
      ...createStationTypeDTO,
      status: createStationTypeDTO.status ?? 1,
      sortOrder: createStationTypeDTO.sortOrder ?? 0
    });

    const savedStationType = await this.stationTypeRepository.save(stationType);
    return this.entityToResponse(savedStationType);
  }

  /**
   * 更新测站类型
   */
  async update(id: string, updateStationTypeDTO: UpdateStationTypeDTO): Promise<StationTypeResponseDTO> {
    const stationType = await this.stationTypeRepository.findOne({ where: { id } });
    if (!stationType) {
      throw new Error('测站类型不存在');
    }

    // 如果更新编码，检查是否重复
    if (updateStationTypeDTO.stationTypeCode && updateStationTypeDTO.stationTypeCode !== stationType.stationTypeCode) {
      const existingType = await this.stationTypeRepository.findOne({
        where: { stationTypeCode: updateStationTypeDTO.stationTypeCode }
      });
      if (existingType) {
        throw new Error('测站类型编码已存在');
      }
    }

    Object.assign(stationType, updateStationTypeDTO);
    const savedStationType = await this.stationTypeRepository.save(stationType);
    return this.entityToResponse(savedStationType);
  }

  /**
   * 删除测站类型
   */
  async delete(id: string): Promise<void> {
    const stationType = await this.stationTypeRepository.findOne({ where: { id } });
    if (!stationType) {
      throw new Error('测站类型不存在');
    }
    
    await this.stationTypeRepository.remove(stationType);
  }

  /**
   * 根据ID查询测站类型
   */
  async findById(id: string): Promise<StationTypeResponseDTO | null> {
    const stationType = await this.stationTypeRepository.findOne({ where: { id } });
    return stationType ? this.entityToResponse(stationType) : null;
  }

  /**
   * 根据编码查询测站类型
   */
  async findByCode(stationTypeCode: string): Promise<StationTypeResponseDTO | null> {
    const stationType = await this.stationTypeRepository.findOne({ 
      where: { stationTypeCode } 
    });
    return stationType ? this.entityToResponse(stationType) : null;
  }

  /**
   * 分页查询测站类型
   */
  async findPage(queryStationTypeDTO: QueryStationTypeDTO): Promise<PageResultDTO<StationTypeResponseDTO>> {
    const { pageNum = 1, pageSize = 10, ...filters } = queryStationTypeDTO;
    
    const queryBuilder = this.stationTypeRepository.createQueryBuilder('stationType');

    // 构建查询条件
    if (filters.stationTypeCode) {
      queryBuilder.andWhere('stationType.stationTypeCode LIKE :stationTypeCode', {
        stationTypeCode: `%${filters.stationTypeCode}%`
      });
    }

    if (filters.stationTypeName) {
      queryBuilder.andWhere('stationType.stationTypeName LIKE :stationTypeName', {
        stationTypeName: `%${filters.stationTypeName}%`
      });
    }

    if (filters.status !== undefined) {
      queryBuilder.andWhere('stationType.status = :status', { status: filters.status });
    }

    if (filters.collectFrequency) {
      queryBuilder.andWhere('stationType.collectFrequency LIKE :collectFrequency', {
        collectFrequency: `%${filters.collectFrequency}%`
      });
    }

    // 排序
    queryBuilder.orderBy('stationType.sortOrder', 'ASC')
                .addOrderBy('stationType.createdAt', 'DESC');

    // 分页
    const skip = (pageNum - 1) * pageSize;
    queryBuilder.skip(skip).take(pageSize);

    const [stationTypes, total] = await queryBuilder.getManyAndCount();

    const list = stationTypes.map(stationType => this.entityToResponse(stationType));
    const totalPages = Math.ceil(total / pageSize);

    return {
      list,
      total,
      pageNum,
      pageSize,
      totalPages
    };
  }

  /**
   * 查询所有测站类型
   */
  async findAll(): Promise<StationTypeResponseDTO[]> {
    const stationTypes = await this.stationTypeRepository.find({
      order: { sortOrder: 'ASC', createdAt: 'DESC' }
    });
    return stationTypes.map(stationType => this.entityToResponse(stationType));
  }

  /**
   * 查询启用的测站类型
   */
  async findEnabled(): Promise<StationTypeResponseDTO[]> {
    const stationTypes = await this.stationTypeRepository.find({
      where: { status: 1 },
      order: { sortOrder: 'ASC', createdAt: 'DESC' }
    });
    return stationTypes.map(stationType => this.entityToResponse(stationType));
  }

  /**
   * 批量导入测站类型
   */
  async batchImport(batchImportDTO: BatchImportStationTypeDTO): Promise<{
    successCount: number;
    failCount: number;
    errors: string[];
  }> {
    const { stationTypeList } = batchImportDTO;
    let successCount = 0;
    let failCount = 0;
    const errors: string[] = [];

    for (const [index, createDTO] of stationTypeList.entries()) {
      try {
        // 检查编码是否已存在
        const existingType = await this.stationTypeRepository.findOne({
          where: { stationTypeCode: createDTO.stationTypeCode }
        });
        
        if (existingType) {
          errors.push(`第${index + 1}行：测站类型编码 ${createDTO.stationTypeCode} 已存在`);
          failCount++;
          continue;
        }

        const stationType = this.stationTypeRepository.create({
          ...createDTO,
          status: createDTO.status ?? 1,
          sortOrder: createDTO.sortOrder ?? 0
        });

        await this.stationTypeRepository.save(stationType);
        successCount++;
      } catch (error) {
        errors.push(`第${index + 1}行：${error.message}`);
        failCount++;
      }
    }

    return { successCount, failCount, errors };
  }

  /**
   * 批量删除测站类型
   */
  async batchDelete(batchDeleteDTO: BatchDeleteDTO): Promise<{
    successCount: number;
    failCount: number;
    errors: string[];
  }> {
    const { ids } = batchDeleteDTO;
    let successCount = 0;
    let failCount = 0;
    const errors: string[] = [];

    for (const id of ids) {
      try {
        const stationType = await this.stationTypeRepository.findOne({ where: { id } });
        if (!stationType) {
          errors.push(`测站类型 ID ${id} 不存在`);
          failCount++;
          continue;
        }

        await this.stationTypeRepository.remove(stationType);
        successCount++;
      } catch (error) {
        errors.push(`删除测站类型 ID ${id} 失败：${error.message}`);
        failCount++;
      }
    }

    return { successCount, failCount, errors };
  }

  /**
   * 更新测站类型状态
   */
  async updateStatus(id: string, status: number): Promise<void> {
    const stationType = await this.stationTypeRepository.findOne({ where: { id } });
    if (!stationType) {
      throw new Error('测站类型不存在');
    }

    stationType.status = status;
    await this.stationTypeRepository.save(stationType);
  }

  /**
   * 检查测站类型编码是否存在
   */
  async checkCodeExists(stationTypeCode: string, excludeId?: string): Promise<boolean> {
    const queryBuilder = this.stationTypeRepository.createQueryBuilder('stationType')
      .where('stationType.stationTypeCode = :stationTypeCode', { stationTypeCode });

    if (excludeId) {
      queryBuilder.andWhere('stationType.id != :excludeId', { excludeId });
    }

    const count = await queryBuilder.getCount();
    return count > 0;
  }

  /**
   * 实体转换为响应DTO
   */
  private entityToResponse(stationType: StationType1): StationTypeResponseDTO {
    return {
      id: stationType.id,
      stationTypeCode: stationType.stationTypeCode,
      stationTypeName: stationType.stationTypeName,
      description: stationType.description,
      collectFrequency: stationType.collectFrequency,
      status: stationType.status,
      sortOrder: stationType.sortOrder,
      remark: stationType.remark,
      createdAt: stationType.createdAt,
      updatedAt: stationType.updatedAt
    };
  }
}